// 服务层的核心文件 封装unirequest
import { deleteObjectEmptyKey, errorLogForRequest } from "../utils/common.js";
import {
  HTTP_SUCCESS_CODES,
  API_SUCCESS_CODES,
} from "@/const/application/service";
// 状态码列表 默认非success中的状态码一律走catch
const REQUEST_CODES = {
  HTTP: {
    success: HTTP_SUCCESS_CODES,
  },
  API: {
    success: API_SUCCESS_CODES,
  },
};

const TIME_OUT = 10000; // 默认超时十秒

let API_SUFFIX = ""; // API前缀

// #ifdef H5
API_SUFFIX = "/api";
// #endif

// #ifdef MP
API_SUFFIX = "/api";
// #endif

const { NODE_ENV, VUE_APP_PLATFORM } = process.env;

if (NODE_ENV !== "development") {
  API_SUFFIX = "";
}

let BASE_URL = process.env.VUE_APP_BASE_URL + API_SUFFIX;
// 基本地址 在.env文件中配置

if (NODE_ENV === "development" && VUE_APP_PLATFORM === "h5") {
  BASE_URL = API_SUFFIX;
}
class Request {
  constructor() {
    this.defaultOptions = {
      isLoading: true, // 是否展示加载弹窗
      loadingOptions: {
        // 加载框选项
        title: "加载中...",
        mask: false,
      },
      callbackOptions: {
        // 返回选项
        all: false, // 是否将response body 全部返回
        errorAll: false, // 是否非成功请求将response body 全部返回
      },
      deleteEmptyKey: true, // 是否删除参数对象中为null的值
      timeoutFn: null, // 超时执行函数
    };
    this.requestTask = [];
    this.headers = {
      "X-APP-ID": "wx84201b9cdb049c25",
      "X-BUSINESS-ID": 41,
      "X-WXAPP-TOKEN":
        " eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3eDg0MjAxYjljZGIwNDljMjUiLCJtZXRob2QiOjUsInZlcnNpb24iOiIxLjAuMCIsInVzZXJfdHlwZSI6IjIiLCJ1c2VyX2lkIjoib0Qwamc1VEhDMUtwMEVIWEdtMEh0cXNrd1l6ayIsInNjb3BlIjoicHViRG9tYWluQ3VzdG9tZXIiLCJuYW1lIjoiQW50aG9ueSIsImlkIjoiOTMzIiwiYnVzaW5lc3NfaWQiOjQxLCJleHAiOjE2NzIzMDM2MjF9.xGhVweNMsngYHM_MABDo1fo9lCPGX4WpkmEciI-QSIo",
    };
    this.loadingCount = 0;
  }
  setHeaders(key, value) {
    this.headers[key] = value;
  }
  get(api, query = null, options = null) {
    return this.request(api, "GET", options?.headers, query, options);
  }
  post(api, data, options = null) {
    return this.request(api, "POST", options?.headers, data, options);
  }
  put(api, query = null, options = null) {
    return this.request(api, "PUT", options?.headers, query, options);
  }
  delete(api, query = null, options = null) {
    return this.request(api, "DELETE", options?.headers, query, options);
  }
  connect(api, query = null, options = null) {
    return this.request(api, "CONNECT", options?.headers, query, options);
  }
  head(api, query = null, options = null) {
    return this.request(api, "HEAD", options?.headers, query, options);
  }
  options(api, data = null, options = null) {
    return this.request(api, "OPTIONS", options?.headers, data, options);
  }
  trace(api, data = null, options = null) {
    return this.request(api, "TRACE", options?.headers, data, options);
  }
  upload(api, files, fileType, file, filePath, name, formData = {}) {
    return new Promise((resolve, reject) => {
      uni.uploadFile({
        url: BASE_URL + api,
        fileType,
        filePath,
        files: files || null,
        file: file || null,
        formData,
        name,
        header: this.headers,
        success: (response) => {
          let { data, statusCode } = response;
          if (typeof data !== "object") {
            data = JSON.parse(data);
          }
          const http_successes =
            REQUEST_CODES.HTTP.success.includes(statusCode); // http 请求是否正常
          const api_successes = REQUEST_CODES.API.success.includes(data.code); // 服务端 response 状态码是否正常
          return http_successes && api_successes
            ? resolve(data.data)
            : reject(data);
        },
        fail: (error) => {
          reject(error);
        },
      });
    });
  }
  request(api, method, headers, data = {}, options = {}) {
    headers = { ...headers, ...this.headers };
    data = data || {};
    options = { ...this.defaultOptions, ...options };
    if (options.isLoading) {
      // 如果开启加载
      uni.showLoading(options.loadingOptions);
      this.loadingCount += 1;
    }
    if (options.deleteEmptyKey) {
      // 删除参数中的null
      data = deleteObjectEmptyKey(data);
    }
    this.onLoading = true;
    return new Promise((resolve, reject) => {
      const _data = data;
      uni.request({
        url: BASE_URL + api,
        method: method || "GET",
        data,
        header: headers,
        timeout: TIME_OUT,
        dataType: options?.dataType,
        responseType: options?.responseType || "text",
        success: (response) => {
          const { data, statusCode } = response;
          const http_successes =
            REQUEST_CODES.HTTP.success.includes(statusCode); // http 请求是否正常
          const api_successes = REQUEST_CODES.API.success.includes(data.code); // 服务端 response 状态码是否正常
          if (
            options.callbackOptions.errorAll &&
            (!http_successes || !api_successes)
          ) {
            errorLogForRequest(api, _data, response);
            return reject(data); // 开启了错误返回返回全部
          }

          if (!http_successes || !api_successes) {
            errorLogForRequest(api, _data, response);
            return reject(data.message); // 单独错误返回
          }
          if (options.callbackOptions.all) resolve(data); // 成功返回全部参数
          resolve(data.data);
        },
        fail: (err) => {
          if (err.errMsg === "request:fail timeout") {
            // 超时判断
            options.timeoutFn && options.timeoutFn(); // 超时处理函数
          }
          errorLogForRequest(api, _data, err);
          reject(err);
        },
        complete: () => {
          if (options.isLoading) {
            this.loadingCount -= 1;
            if (!this.loadingCount) uni.hideLoading();
          }
        },
      });
    });
  }
}

const request = new Request();

export default request;
